package org.budo.canal.instance.spring;

import org.budo.support.lang.util.ReflectUtil;

import com.alibaba.otter.canal.instance.core.CanalInstance;
import com.alibaba.otter.canal.instance.spring.CanalInstanceWithSpring;
import com.alibaba.otter.canal.parse.inbound.AbstractEventParser;
import com.alibaba.otter.canal.parse.inbound.mysql.MysqlEventParser;
import com.alibaba.otter.canal.sink.entry.EntryEventSink;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * 不指定 destination 时默认以 beanName 为 destination
 * 
 * @see com.alibaba.otter.canal.instance.spring.CanalInstanceWithSpring
 */
@Slf4j
@Getter
@Setter
public class CanalInstanceFactoryBean extends AbstractCanalInstanceFactoryBean {
    @Override
    public CanalInstance getObject() throws Exception {
        if (null == this.masterInfo()) {
            log.error("#27 masterInfo return null, this=" + this);
            return null;
        }

        // EventSink 默认值
        if (null == this.getEventSink() && null != this.getEventStore()) {
            EntryEventSink entryEventSink = new EntryEventSink();
            entryEventSink.setEventStore(this.getEventStore());
            this.setEventSink(entryEventSink);
        }

        // EventParser.masterInfo 默认值
        if (null != this.masterInfo() && null != this.getEventParser() //
                && this.getEventParser() instanceof MysqlEventParser //
                && null == ReflectUtil.getFieldValue(this.getEventParser(), "masterInfo")) {
            ((MysqlEventParser) this.getEventParser()).setMasterInfo(this.masterInfo());
        }

        // EventParser.eventSink 默认值
        if (null != this.getEventSink() && null != this.getEventParser() //
                && this.getEventParser() instanceof AbstractEventParser //
                && null == ReflectUtil.getFieldValue(this.getEventParser(), "eventSink")) {
            ((AbstractEventParser) this.getEventParser()).setEventSink(this.getEventSink());
        }

        CanalInstanceWithSpring canalInstance = new CanalInstanceWithSpring();
        canalInstance.setEventSink(this.getEventSink());

        canalInstance.setDestination(this.destination());
        canalInstance.setMetaManager(this.getMetaManager());
        canalInstance.setEventStore(this.getEventStore());
        canalInstance.setEventParser(this.getEventParser());
        canalInstance.setAlarmHandler(this.getAlarmHandler());

        log.info("#92 canalInstance=" + canalInstance + ", not starting");
        return canalInstance;
    }

    @Override
    public String toString() {
        return super.toString() //
                + ", destination=" + this.destination() //
                + ", eventParser=" + this.getEventParser() //
                + ", masterInfo=" + this.getMasterInfo() //
                + ", host=" + this.getHost() //
                + ", port=" + this.getPort() //
                + ", username=" + this.getUsername();
    }
}
